//-------------------------------------------------------------------
//	Copyright (c) 2012-2014 Zhirnov Andrey
//	This file is part of the "UXGEN-ES" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#pragma once

#include "Base/Include/Common.h"
#include "Base/Include/EngineSubSystems.h"
#include "Platforms/Base/Enums.h"


namespace Engine
{
namespace Platforms
{
	using namespace Base;



	//
	// Hardware Camera
	//
	
	class HardwareCamera
	{
	// types
	public:

		struct ImageFormat
		{
			enum type
			{
				UNKNOWN		= 0,
				JPEG		= 0x00000100,
				NV16		= 0x00000010,
				NV21		= 0x00000011,
				RGB_565		= 0x00000004,
				YUV_420_888	= 0x00000023,
				YUY2		= 0x00000014,
				YV12		= 0x32315659,
			};
		};

		struct Antibanding
		{
			enum type
			{
				OFF  		= 0,
				FREQ_50HZ  	= 1,
				FREQ_60HZ 	= 2,
				AUTO 		= 3,
			};
		};

		struct Effect
		{
			enum type
			{
				NONE 		= 0,
				AQUA 		= 1,
				BLACKBOARD 	= 2,
				MONO		= 3,
				NEGATIVE 	= 4,
				POSTERIZE 	= 5,
				SEPIA 		= 6,
				SOLARIZE 	= 7,
				WHITEBOARD 	= 8,
			};
		};

		struct FlashMode
		{
			enum type
			{
				OFF 	= 0,
				AUTO 	= 1,
				ON 		= 2,
				RED_EYE	= 3,
				TORCH 	= 4,
			};
		};

		struct FocusMode
		{
			enum type
			{
				AUTO 				= 0,
				CONTINUOUS_PICTURE  = 1,
				CONTINUOUS_VIDEO 	= 2,
				EDOF 				= 3,
				FIXED 				= 4,
				INFINITY 			= 5,
				MACRO 				= 6,
			};
		};
	
		struct SceneMode
		{
			enum type
			{
				AUTO			= 0,
				ACTION 			= 1,
				BARCODE 		= 2,
				BEACH			= 3,
				CANDLELIGHT 	= 4,
				FIREWORKS 		= 5,
				HDR				= 6,
				LANDSCAPE 		= 7,
				NIGHT			= 8,
				NIGHT_PORTRAIT	= 9,
				PARTY 			= 10,
				PORTRAIT 		= 11,
				SNOW 			= 12,
				SPORTS			= 13,
				STEADYPHOTO 	= 14,
				SUNSET 			= 15,
				THEATRE 		= 16,
			};
		};

		struct WhiteBalance
		{
			enum type
			{
				AUTO 				= 0,
				CLOUDY_DAYLIGHT		= 1,
				DAYLIGHT 			= 2,
				FLUORESCENT			= 3,
				INCANDESCENT 		= 4,
				SHADE 				= 5,
				TWILIGHT			= 6,
				WARM_FLUORESCENT 	= 7,
			};
		};


		struct Face
		{
			int		id;
			int		score;
			frect	region;
			vec2	leftEye;
			vec2	rightEye;
			vec2	mouse;
			///
			Face () : id(-1), score(0) {}
		};


		// Data Types //
		typedef uni_array< const ivec2 >				ivec2_arr_t;
		typedef uni_array< const ImageFormat::type >	format_arr_t;
		typedef uni_array< const Face >					face_arr_t;
		typedef uni_array< const Antibanding::type >	antibanding_arr_t;
		typedef uni_array< const Effect::type >			effect_arr_t;
		typedef uni_array< const FlashMode::type >		flashmode_arr_t;
		typedef uni_array< const FocusMode::type >		focusmode_arr_t;
		typedef uni_array< const SceneMode::type >		scenemode_arr_t;
		typedef uni_array< const WhiteBalance::type >	whitebalance_arr_t;


		// Callback Types //
		typedef delegate< void (const uni_binbuffer_t &data, const ivec2 &dim, ImageFormat::type fmt) >	OnImageCallback_t;
		typedef delegate< void (const face_arr_t faces, uint lastAddedFaceIndex) >						OnFaceDetected_t;
	

	// interface
	public:

		// callbacks
		virtual void SetPreviewCallback (OnImageCallback_t cb) = 0;
		virtual void SetPictureCallback (OnImageCallback_t cb) = 0;
		virtual void SetFaceDetectedCallback (OnFaceDetected_t cb) = 0;

		// actions
		virtual void Enable (bool enable) = 0;
		virtual void Open (uint cameraIndex = 0) = 0;
		virtual void Close (bool saveState = false) = 0;
		virtual void StartFaceDetection () = 0;
		virtual void StopFaceDetection () = 0;
		virtual void AutoFocus () = 0;

		// get params
		virtual bool				IsEnabled ()			const = 0;
		virtual ivec2_arr_t			GetPreviewFpsRanges ()	const = 0;
		virtual ivec2_arr_t			GetPreviewSizes ()		const = 0;
		virtual format_arr_t		GetPreviewFormats ()	const = 0;
		virtual ivec2_arr_t			GetPictureSizes ()		const = 0;
		virtual format_arr_t		GetPictureFormats ()	const = 0;
		virtual antibanding_arr_t	GetAntibandings ()		const = 0;
		virtual effect_arr_t		GetEffects ()			const = 0;
		virtual flashmode_arr_t		GetFlashModes ()		const = 0;
		virtual focusmode_arr_t		GetFocusModes ()		const = 0;
		virtual scenemode_arr_t		GetSceneModes ()		const = 0;
		virtual whitebalance_arr_t	GetWhiteBalance ()		const = 0;

		virtual ivec2				GetExposureLimits ()	const = 0;
		
		
		// shared preview/picture parameters
		virtual void SetZoom (uint value) = 0;
		virtual void SetZoomNorm (float value) = 0;
		virtual void SetSmoothZoom (uint value) = 0;
		virtual void SetSmoothZoomNorm (float value) = 0;
		virtual void SetExposure (int value) = 0;
		virtual void SetExposureNorm (float value) = 0;
		virtual void SetAntibanding (Antibanding::type value) = 0;
		virtual void SetColorEffect (Effect::type value) = 0;
		virtual void SetFlashMode (FlashMode::type value) = 0;
		virtual void SetFocusMode (FocusMode::type value) = 0;
		virtual void SetSceneMode (SceneMode::type value) = 0;
		virtual void SetWhiteBalance (WhiteBalance::type value) = 0;

		// preview parameters
		virtual void SetPreviewSize (const ivec2 &size) = 0;
		virtual void SetPreviewNearSize (const ivec2 &size) = 0;
		virtual void SetPreviewFormat (ImageFormat::type fmt) = 0;
		virtual void SetPreviewFPS (uint minFPS, uint maxFPS) = 0;
		virtual void SetPreviewNearFPS (float fps) = 0;
		//virtual void SetPreviewBuffers (uint buffers) = 0;

		// picture parameters
		virtual void TakePicture (bool autoFocus) = 0;
		virtual void SetPictureSize (const ivec2 &size) = 0;
		virtual void SetPictureNearSize (const ivec2 &size) = 0;
		virtual void SetPictureFormat (ImageFormat::type fmt) = 0;
		virtual void SetJpegQuality (uint quality) = 0;		// 0..100
	};


}	// Platforms
}	// Engine